//
//  ECBaseViewController.swift
//  ECBase
//
//  Created by Tony on 2020/4/28.
//

import Foundation
import UIKit
import SnapKit
import Kingfisher


public enum XYPresentType {
    case push
    case pop
    case present
    case presentWithNav
    case dismiss
    case popToRoot
}

public enum XYBarStyle {
    case white
    case black
    case clear
}

public class XYNavigationBarItem: UIControl {
    var actionBlock: ((XYNavigationBarItem?)->Void)?
    public var titleLabel: UILabel?
    public var imageView : UIImageView?
    
    public init(title: String, width: CGFloat = 44, action:((XYNavigationBarItem?)->Void)?=nil) {
        super.init(frame: CGRect(x: 0, y: 0, width: width, height: 44))
        self.update(title, width: width)
        self.update(action)
        self.addTarget(self, action: #selector(controlClicked), for: .touchUpInside)
    }
    
    public init(image: String, size: CGSize = CGSize(width: 44, height: 44), contentMode: UIView.ContentMode = .center, action:((XYNavigationBarItem?)->Void)?=nil) {
        super.init(frame: CGRect(x: 0, y: 0, width: size.width, height:max(size.height, 44)))
        self.update(image.trimmingCharacters(in: CharacterSet.whitespaces), size: size, contentMode: contentMode)
        self.update(action)
        self.addTarget(self, action: #selector(controlClicked), for: .touchUpInside)
    }
    
    public init(view: UIView, action:((XYNavigationBarItem?)->Void)?=nil) {
        super.init(frame: CGRect(x: 0, y: 0, width: view.bounds.size.width, height:44))
        self.update(view)
        self.update(action)
        self.addTarget(self, action: #selector(controlClicked), for: .touchUpInside)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    public func update(_ title: String, width: CGFloat = 44) {
        while self.subviews.count > 0 {
            self.subviews.last?.removeFromSuperview()
        }
        let titleLabel = UILabel(frame: CGRect.zero)
        titleLabel.font = UIFont.systemFont(ofSize: 13)
        titleLabel.textAlignment = .center
        titleLabel.text = title
        self.titleLabel = titleLabel
        self.addSubview(titleLabel)
        
        titleLabel.snp.makeConstraints {
            $0.edges.equalTo(UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0))
            $0.width.equalTo(width)
        }
    }
    
    public func update(_ view: UIView) {
        while self.subviews.count > 0 {
            self.subviews.last?.removeFromSuperview()
        }
        self.addSubview(view)
        view.snp.makeConstraints {
            $0.size.equalTo(CGSize(width: view.bounds.size.width, height: view.bounds.size.height))
            $0.left.equalTo(0)
            $0.centerY.equalToSuperview()
        }
    }
    
    public func update(_ image: String, size: CGSize = CGSize(width: 44, height: 44), contentMode: UIView.ContentMode) {
        while self.subviews.count > 0 {
            self.subviews.last?.removeFromSuperview()
        }
        let imageView = UIImageView(frame: CGRect.zero)
        imageView.contentMode = contentMode
        if (image.hasPrefix("http") || image.hasPrefix("file://")), let url = URL(string: image) {
            imageView.kf.setImage(with: url, placeholder: UIImage(named: ""), options: nil, progressBlock: nil, completionHandler: nil)
        } else {
            imageView.image = UIImage(named: image) ?? UIImage(named: "")
        }
        self.imageView = imageView
        self.addSubview(imageView)
        imageView.snp.makeConstraints {
            $0.size.equalTo(size)
            $0.center.equalTo(self)
        }
    }
    
    public func update(_ action: ((XYNavigationBarItem?)->Void)?) {
        self.actionBlock = action
    }
    
    @objc func controlClicked() {
        weak var weakSelf = self
        actionBlock?(weakSelf)
    }
}

public class XYNavigationBar: UIView {
    public var style = XYBarStyle.white
    
    public var statusBarStyle: UIStatusBarStyle {
        switch style {
        case .black, .clear:
            return .lightContent
        case .white:
            return .default
        }
    }
    
    public override var isHidden: Bool {
        didSet {
            self.superview?.bringSubviewToFront(self)
        }
    }
    
    var titleView: UIView? {
        didSet {
            oldValue?.removeFromSuperview()
            
            if let x = titleView {
                addSubview(x)
                x.snp_makeConstraints { (m) in
                    m.edges.equalTo(titleLabel)
                }
                
                titleLabel.isHidden = true
            }
        }
    }
    
    lazy var leftView: UIView = UIView()
    lazy var titleLabel: UILabel = {
        let lb = UILabel()
        lb.font = UIFont.systemFont(ofSize: 16)
        lb.textColor = .black
        lb.textAlignment = .center
        return lb
    }()
    
    lazy var rightView: UIView = UIView()
    lazy var lineView: UIView = {
        let result = UIView()
        result.isHidden = true
        result.backgroundColor = UIColor.white
        return result
    }()
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        self.addSubview(leftView)
        self.addSubview(titleLabel)
        self.addSubview(rightView)
        self.addSubview(lineView)
        leftView.snp.makeConstraints {
            $0.left.equalTo(15)
            $0.bottom.equalTo(0)
            $0.height.width.equalTo(44)
        }
        rightView.snp.makeConstraints {
            $0.right.equalTo(-10)
            $0.bottom.equalTo(0)
            $0.height.width.equalTo(44)
        }
        titleLabel.snp.makeConstraints {
            $0.centerX.equalTo(self)
            $0.bottom.equalTo(0)
            $0.width.equalTo(200)
            $0.height.equalTo(44)
        }
        lineView.snp.makeConstraints {
            $0.height.equalTo(2)
            $0.left.bottom.right.equalTo(0)
        }
        
        update(style: .white)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    public func update(title: String) {
        titleLabel.text = title
        titleLabel.isHidden = false
        titleView?.isHidden = true
    }
    
    public func update(style: XYBarStyle) {
        self.style = style
        
        switch style {
        case .black:
            backgroundColor = .black
            titleLabel.textColor = .white
        case .white:
            backgroundColor = .white
            titleLabel.textColor = .black
        case .clear:
            backgroundColor = .clear
            titleLabel.textColor = .black
        }
        
        ctr?.setNeedsStatusBarAppearanceUpdate()
    }
    
    public func update(leftItems: [XYNavigationBarItem]?) {
        while leftView.subviews.count > 0 {
            leftView.subviews.last?.removeFromSuperview()
        }
        guard let leftItems = leftItems, leftItems.count > 0 else { return }
        var width: CGFloat = 0
        for item in leftItems {
            item.frame.origin = CGPoint(x: width, y: item.frame.origin.y)
            leftView.addSubview(item)
            width += item.bounds.size.width + 15
        }
        leftView.snp.updateConstraints {
            $0.width.equalTo(width)
        }
    }
    
    public func update(rightItems: [XYNavigationBarItem]?) {
        while rightView.subviews.count > 0 {
            rightView.subviews.last?.removeFromSuperview()
        }
        guard let rightItems = rightItems, rightItems.count > 0 else { return }
        var width: CGFloat = 0
        for item in rightItems {
            item.frame.origin = CGPoint(x: width, y: item.frame.origin.y)
            rightView.addSubview(item)
            width += item.bounds.size.width + 15
        }
        rightView.snp.updateConstraints {
            $0.width.equalTo(width)
        }
    }
    
    public func update(hideLine: Bool) {
        self.lineView.isHidden = hideLine
    }
}

open class XYBaseViewController: UIViewController, XYBaseViewControllerProtocol {
    public var bar: XYNavigationBar = XYNavigationBar(frame: CGRect.zero)
    weak var popViewController: UIViewController?
    public var isEnableEnterForegroundNotifi = false {
        didSet {
            if isEnableEnterForegroundNotifi {
                registerEnterForgroundNotifi()
            } else {
                NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
            }
        }
    }
    
    public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        self.modalPresentationStyle = .overCurrentContext
    }
    
    open override var preferredStatusBarStyle: UIStatusBarStyle {
        return bar.statusBarStyle
    }

    deinit {
        guard isEnableEnterForegroundNotifi == true else {  return  }
        NotificationCenter.default.removeObserver(self)
    }
    
    required public init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override open func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        bar.backgroundColor = UIColor.clear
        // navbar
        self.view.addSubview(bar)
        
        var barHeight = UIApplication.shared.statusBarFrame.height
        if barHeight < 1 {
            barHeight = UIScreen.main.bounds.height >= 812 ? 44 : 20
        }
        bar.snp.makeConstraints {
            $0.left.top.right.equalTo(0)
            $0.height.equalTo(barHeight + 44)
        }
        if self.navigationController?.viewControllers.count ?? 0 > 1 {
            // 默认显示返回按钮
            showBackItem()
        }
    }
    
//    func getEmptyView(_ type: EmptyType, frame: CGRect = CGRect(x: 0, y:0, width: UIScreen.width, height: UIScreen.height)) -> TWEmptyView {
//        let result = TWEmptyView(type, frame: frame) {[weak self] (emptyView) in
//            guard let `self` = self else {
//                return
//            }
//            self.emptyViewRetry()
//        }
//        result.backgroundColor = UIColor.init(withHex: "#F2F6FA")
//        return result
//    }
    
    public func showBackItem() -> Void {
        let backItem = createBackItem()
        bar.update(leftItems: [backItem])
    }
    
    public func createBackItem() -> XYNavigationBarItem {
        let style = bar.style == .white ? "black":"white"
        let action = canPop ? "back":"close"
        let imgName = "navbar_\(action)_\(style)"
        return XYNavigationBarItem(image: imgName, size: CGSize(width: 20, height: 44), action: {[unowned self](item) in
            self.backItemClicked()
        })
    }
    
    func registerEnterForgroundNotifi() {
        NotificationCenter.default.addObserver(self, selector: #selector(self.applicationEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
    }
    
    @objc open func backItemClicked() {
        if canPop {
            self.handleVC(nil, type: .pop)
        } else {
            self.handleVC(nil, type: .dismiss)
        }
    }
    
    public class func needLogin() -> Bool {
        return false
    }
    
    open func didReceiveParam(_ param: [String : Any], presentType: XYPresentType) {
        // 处理公共参数
    }
    
    @objc open func applicationEnterForeground() {
        // App 热启动，子类实现
    }
    
    public func emptyViewRetry() {
        
    }
}

public extension UIViewController {
    var xy_isLoaded: Bool {
        self.isViewLoaded && self.view.window != nil
    }
    
    var canPop: Bool {
        return navigationController?.viewControllers.count ?? 0 > 1
    }
}

public extension UIResponder {
    var ctr: UIViewController? {
        //获取当前view的superView对应的控制器
        var next = self.next
        
        while next != nil {
            if next!.isKind(of: UIViewController.self) {
                return (next as? UIViewController)
            }
            next = next!.next
        }
        
        return nil
    }
}
